package com.ly.mpayment.rest.up.chinaunicom;

import com.ailk.upp.client.UppClient;
import com.alibaba.fastjson.JSONObject;
import com.ly.mpayment.core.secuity.Base64;
import com.ly.mpayment.core.secuity.MD5;
import com.ly.mpayment.core.util.*;
import com.ly.mpayment.persist.entity.UpOrder;
import com.ly.mpayment.persist.entity.UpShopInfo;
import com.ly.mpayment.persist.service.downrechargeflow.IDownRechargeFlowService;
import com.ly.mpayment.persist.service.downshopinfo.IDownShopInfoService;
import com.ly.mpayment.persist.service.uporder.IUporderService;
import com.ly.mpayment.persist.service.upshopinfo.IUpShopInfoService;
import com.ly.mpayment.rest.recharge.RechargeRest;
import com.ly.mpayment.rest.up.util.Util;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.log4j.Logger;
import org.mortbay.util.MultiMap;
import org.mortbay.util.UrlEncoded;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestBody;

import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.QueryParam;
import java.net.Authenticator;
import java.util.*;

@Component
@Path("chinaunicom")
public class ChinaUnicomRest {

    Logger logger = Logger.getLogger(ChinaUnicomRest.class);

    @Autowired
    IUporderService upOrderService;

    @Autowired
    private ThreadPoolTaskExecutor taskExecutor;

    @Autowired
    IDownRechargeFlowService flowService;

    @Autowired
    IDownShopInfoService shopService;

    @Autowired
    IUpShopInfoService upShopInfoService;

    public void queryOrder(UpOrder order, UpShopInfo shop) {
        Map<String,String> bizMap = new HashMap<String,String>();
        bizMap.put("parterNo", shop.getAppId());
        bizMap.put("tradeID", Util.getBatchNO());
        bizMap.put("timeStamp", new DateUtils().toTimeStamp());
        bizMap.put("payTradeID", order.getUporderuuid());

        logger.info("commitquery_chinaunicom:"+bizMap);
        UppClient uppClient = new UppClient(shop.getOrderStatusAddress(),"com.ailk.upp.tradequery",shop.getUpkey());
        try {
            Map excute = uppClient.excute(bizMap);
            String authenticator = uppClient.getAuthenticator(excute);
            if(!authenticator.equals(excute.get("authenticator"))){
                logger.info("commitquery_chinaunicom_签名失败:"+authenticator);
            }
            logger.info("commitquery_chinaunicom:"+excute);
//            payState=1 和 tradeState=1下订单是成功的。
//            payState=2 或 tradeState=2下订单可以退款的。
//            其余情况等对账
            if(excute != null){
                if(excute.get("result").toString().substring(2,6).equals("0000") && excute.get("tradeState").toString().equals("1")
                        && excute.get("payState").toString().equals("1")){
                    order.setRemark( excute.containsKey("orderNo") ? excute.get("orderNo").toString() : excute.get("resultDesc").toString());
                    RechargeRest.successUpOrder.add(order);
                } else if(excute.get("result").toString().substring(2,6).equals("0000") && (
                        excute.get("tradeState").toString().equals("2")
                                || excute.get("payState").toString().equals("2")
                        )){
                    order.setRemark(excute.containsKey("desc") ? excute.get("desc").toString() : excute.get("resultDesc").toString());
                    RechargeRest.failtUpOrder.add(order);
                }else {
                    upOrderService.updateUpOrderMsg(order, "",excute.get("resultDesc").toString());
                }
            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    /**
     * 手机异步交费	com.ailk.upp.asyncmobilepayfee
     * 固话异步交费	com.ailk.upp.asyncfixpayfee
     * 宽带异步交费	com.ailk.upp.asyncbroadbandpayfee
     * 单笔订单查询	com.ailk.upp.tradequery
     * @param order
     * @param shop
     */
    public void commitOrder(UpOrder order, UpShopInfo shop) {
        String timeStamp = new DateUtils().toTimeStamp();
        Map<String,String> bizMap = new HashMap<String,String>();
        bizMap.put("parterNo",shop.getAppId());
        bizMap.put("tradeID",order.getUporderuuid());
        bizMap.put("phoneNo",order.getUpphonenum());
        bizMap.put("fee",Integer.parseInt(order.getUpShopPro().getUpfacevalue()) * 100+"");
        bizMap.put("callbackUrl",shop.getOrderCallAddress());
        bizMap.put("mediaType","01");
        bizMap.put("requestTime",timeStamp);
        //用户支付时间比订单时间滞后，因先下单后支付
        bizMap.put("userPayTime",DateUtils.parseTimeStamp(new Date((System.currentTimeMillis()+Long.valueOf((long) (Math.random()*3))))));

//        data.put("payOrgOrder",order.getUporderuuid());
//        data.put("payOrgMethod","pay_online");
//        data.put("provider","01");
        logger.info("commitOrder_chinaunicom:"+bizMap);
        UppClient uppClient = new UppClient(shop.getOrderCommitAddress(),"com.ailk.upp.asyncmobilepayfee",shop.getUpkey());
        try {
            Map excute = uppClient.excute(bizMap);
            String authenticator = uppClient.getAuthenticator(excute);
            if(!authenticator.equals(excute.get("authenticator"))){
                logger.info("commitOrder_签名失败:"+authenticator);
            }
            //{"result":"1G0000","fee":"1000","parterNo":"2410000503","resultDesc":"受理成功","authenticator":"hxy23i9onq+B3xZ8Q64EZV/OYH4IAAGJbEutDKCiFnk=",
            // "phoneNo":"18611111234","processTime":"20211117211443","tradeID":"2c922ab97d2e082e017d2e0901440005"}
            logger.info("commitOrder:"+excute+","+order.getUpphonenum());
            if(excute != null){
                if(excute.get("result").toString().substring(2,6).equals("0000")){
                    upOrderService.updateUpOrderMsg(order,excute.get("tradeID").toString(), excute.get("resultDesc").toString());
                }else if(errorCode.contains(excute.get("result").toString().substring(2,6))){
                    order.setRemark(excute.get("resultDesc").toString());
                    RechargeRest.failtUpOrder.add(order);
                }else{
                    upOrderService.updateUpOrderMsg(order, "",excute.get("resultDesc").toString());
                }
            }else{
                upOrderService.updateUpOrderArtificial(order, "","提单失败:");
            }
        }catch (Exception e){
            e.printStackTrace();
            upOrderService.updateUpOrderArtificial(order, "","提单失败:"+e.getMessage());
        }
    }


    /**
     *  XX0000	受理成功	受理成功
     *  XX9002	流水号重复	受理失败
     * 	XX9004	接口鉴权未通过	受理失败
     * 	XX9005	签名校验未通过	受理失败
     * 	XX9006	业务规则限制校验未通过	受理失败
     * 	XX9007	参数校验未通过	受理失败
     * 	XX9008	业务平台编码不存在	受理失败
     * 	XX9301	业务受理纪录新增失败	受理失败
     * 	XX9302	业务受理纪录更新失败	受理失败
     * 	XX9998	业务处理失败	受理失败
     * 	XX9999	系统异常	受理异常
     */
    Set<String> errorCode = new HashSet<String>(){{
        add("9002");
        add("9004");
        add("9005");
        add("9006");
        add("9007");
        add("9008");
        add("9301");
        add("9302");
        add("9998");
        add("9009");
    }};

    /**
     * XX3001	支付失败	交费失败	是
     * XX2001	用户号码不存在	交费失败	是
     * XX2002	智能网用户，不支持对该用户类型的缴费	交费失败	是
     * XX2003	缴费金额不正确	交费失败	是
     * XX2004	系统出账，不能缴费	交费失败	是
     * XX2008	用户不在充值期，暂不容许缴费	交费失败	是
     * XX2101	无订购关系	交费失败	是
     * XX2201	不允许跨月查询	交费失败	是
     * XX2202	号码不存在	交费失败	是
     * XX2203	号码状态不正确	交费失败	是
     * XX9995	正在退款中	交费失败	是
     * XX8900	退款成功	交费失败	是
     * XX9001	订单不存在	交费失败	是
     * XX9002	订单号重复	交费失败	是
     * XX9003	订单状态不正确	交费失败	是
     * XX9004	接口鉴权未通过	交费失败	是
     * XX9005	签名校验未通过	交费失败	是
     * XX9006	业务规则限制校验未通过	交费失败	是
     * XX9007	参数校验未通过	交费失败	是
     * XX9008	业务平台编码不存在	交费失败	是
     * XX9201	订单生成失败	交费失败	是
     * XX9202	订单支付更新失败	交费失败	是
     * XX9204	第三方余额账户金额不足	交费失败	是
     * XX9301	业务受理纪录新增失败	交费失败	是
     * XX9997	交费金额验证失败	交费失败	是
     * XX9998	业务处理失败	交费失败	是
     */
    Set<String> errorCodeCall = new HashSet<String>(){{
        add("3001");
        add("2001");
        add("2002");
        add("2003");
        add("2004");
        add("2008");
        add("2201");
        add("2202");
        add("2203");
        add("9995");
        add("8900");
        add("9001");
        add("9002");
        add("9003");
        add("9004");
        add("9005");
        add("9006");
        add("9007");
        add("9008");
        add("9201");
        add("9202");
        add("9204");
        add("9301");
        add("9997");
        add("9998");
        add("9999");
    }};

    /**
     * requestTime=20211117211441&result=1D0000&payNo=301000100100221111721152800009&orderNo=100101101052111172115022000027&
     * payTime=20211117211539&fee=1000&completeTime=20211117211545&mediaType=01&parterNo=2410000503&resultDesc=%E4%BA%A4%E8%B4%B9%E6%88%90%E5%8A%9F
     * &tradeID=2c922ab97d2e082e017d2e0901440005&phoneNo=18611111234
     * @param data
     * @return
     */
    @Path("callBack")
    @POST
    public String callBack( @RequestBody String data){
        logger.info("chinaunicomcallBack:"+data);
        if(!StringUtils.isBlank(data)){
            MultiMap multiMap = parceString(data);
            UpOrder order = upOrderService.findById(multiMap.getString("tradeID"));
            if(order != null ){
                if (order != null && multiMap.getString("result").substring(2,6).equals("0000") && order.getStatus() == Config.status[0]) {
                    order.setRemark(multiMap.getString("orderNo"));
                    RechargeRest.successUpOrder.add(order);
                    return "SUCCESS";
                }else if(order != null && order.getStatus() == Config.status[0] && errorCodeCall.contains(multiMap.getString("result").substring(2,6)) ){
                    order.setRemark(multiMap.getString("resultDesc"));
                    RechargeRest.failtUpOrder.add(order);
                    return "SUCCESS";
                }else{
                    logger.info("chinaunicomcallBack_not_found_order:" + data );
                }
            }else {
                logger.info("未找到订单:"+data);
            }
        }
        return "SUCCESS";
    }

    private MultiMap parceString(String str){
        MultiMap map = new MultiMap();
        UrlEncoded.decodeTo(str, map, "utf-8");
        return map;
    }
}
